# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: db\mysql.py
__author__ = "Attila Gerendi (Sanyi)"
import threading
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool
from settings_provider import settings

DATABASES = {}
POOL_SIZE = 20
MAX_OVERFLOW = 20
POOL_RECYCLE = 3600


def ping_connection(dbapi_connection, connection_record, connection_proxy):
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        connection_proxy._pool.dispose()
        raise exc.DisconnectionError()

    cursor.close()


def register_pessimistic_connection_handling():
    event.listen(Pool, "checkout", ping_connection)


db_engine_cache = {}
db_engine_cache_lock = threading.Lock()
session_cache = {}
session_cache_lock = threading.Lock()


def get_engine_by_database_name(db_name, isolation_level=None):
    db_cache_hash_key = "%s--%s" % (db_name, isolation_level)
    with db_engine_cache_lock:
        engine = db_engine_cache.get(db_cache_hash_key, None)
        if engine:
            return engine
        db_record = settings["databases"]["connections"][db_name]["connection"]
        if not settings["databases"]["connections"][db_name]["type"] == "mysql":
            raise AssertionError
        cs = "mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8&use_unicode=0" % (
            db_record["user"],
            db_record["password"],
            db_record["host"],
            db_record["port"],
            db_record["db"],
        )
        kwargs = dict(
            echo=settings["databases.debug"],
            pool_size=POOL_SIZE,
            max_overflow=MAX_OVERFLOW,
            pool_recycle=POOL_RECYCLE,
        )
        if isolation_level:
            kwargs["isolation_level"] = isolation_level
        engine = create_engine(cs, **kwargs)
        db_engine_cache[db_cache_hash_key] = engine
        return engine


def session_maker(db_name, isolation_level=None):
    session_cache_hash_key = "%s--%s" % (db_name, isolation_level)
    with session_cache_lock:
        session = session_cache.get(session_cache_hash_key, None)
        if session:
            return session()
        session = sessionmaker(get_engine_by_database_name(db_name, isolation_level))
        session_cache[session_cache_hash_key] = session
        return session()


def master_session_maker():
    return session_maker("master")


class Connection:
    def __init__(self, name, isolation_level=None):
        self.name = name
        self.isolation_level = isolation_level
        self.connection = None

    def __enter__(self):
        self.connection = get_engine_by_database_name(
            self.name, self.isolation_level
        ).connect()
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.connection:
            self.connection.close()
            self.connection = None


class Session:
    def __init__(self, name, auto_commit=True, isolation_level=None):
        self.name = name
        self._session = None
        self._auto_commit = auto_commit
        self._isolation_level = isolation_level

    def __enter__(self):
        self._session = session_maker(self.name, self._isolation_level)
        return self._session

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self._session:
            if self._auto_commit:
                self._session.commit()
            self._session.close()
            self._session = None
